package com.lock;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Java中的读写锁
 * @program: study
 * @className: JavaLock
 * @description: TODO
 * @author: kukuxiahuni
 * @create: 2020-02-11 10:30
 **/
public class JavaLock {

    public static void main(String[] args) {
        final ReentrantReadWriteLock.ReadLock readLock;
        final ReentrantReadWriteLock.WriteLock writeLock;

        /**
         * 抢占锁
         */
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);

        readLock = lock.readLock();
        writeLock = lock.writeLock();

        System.out.println("main: before readlock lock");
        readLock.lock();
        System.out.println("main: after readlock lock");

        Thread tw = new Thread(){
            public void run() {
                System.out.println("tw: before writelock lock");
                writeLock.lock();
                System.out.println("tw: after writelock lock");
            }
        };
        Thread tr = new Thread(){
            public void run() {
                System.out.println("tr: before readlock lock");
                readLock.lock();
                System.out.println("tr: after readlock lock");
            }
        };

        try {
            tw.start();
            Thread.sleep(1000);
            tr.start();
            tw.join();
            tr.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    /**
    * @method: 读写锁使用demo
    * @param:
    * @return:
    * @author: kukuxiahuni
    * @create: 2020/2/11 10:57
    * @modify_user:TODO
    * @modify_time: 2020/2/11 10:57
    **/
    private final static class Cache{
        private final Map<String, String> cache = new HashMap<>();
        /**
         * 读写锁
         */
        private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);
        /**
         * 读锁
         */
        private final ReentrantReadWriteLock.ReadLock rLock = lock.readLock();
        private final ReentrantReadWriteLock.WriteLock wLock = lock.writeLock();

        /**
        * @method: 根据key获取值
        * @param:
        * @return:
        * @author: kukuxiahuni
        * @create: 2020/2/11 11:01
        * @modify_user:TODO
        * @modify_time: 2020/2/11 11:01
        **/
        public String get(String key) {

            rLock.lock();
            try {
                return this.cache.get(key);
            } finally {
                rLock.unlock();
            }

        }

        public final void put(String key, String value) {

            wLock.lock();
            try {
                this.cache.put(key, value);
            }finally {
                wLock.unlock();
            }
        }

        public final void remove(String key) {
            wLock.lock();
            try {
                this.cache.remove(key);
            } finally {
                wLock.unlock();
            }
        }


    }
}
